

public class MS_HeikoGrams2 extends Algo {

	public MS_HeikoGrams2(int grad, int maxRunden) {
		super(grad, maxRunden);
	}
		

	public void optimieren() {
		double arrNeu[] = new double[arrBest.length];
		double fitnessNeu;
		double sigma = 2; // TODO vom user vorgeben lassen ....?
		double mindestFitness = 0.20; /* schlechter soll die fitness nicht sein, vorher nicht aufhoeren; BEI Grad=1 endet das Programm nicht ohne Abbruch!!*/
		double sigmaMin = 0.00001; //  TODO ... schauen was da so geht
		int n = 0;
		fitnessBest = eval(arrBest);

		do {
			do {
				mutation(arrNeu, arrBest, sigma);
				fitnessNeu = eval(arrNeu);

				if (fitnessNeu < fitnessBest) {
					arrBest = arrNeu.clone();
					fitnessBest = fitnessNeu;
					sigma *= 2;
				} else {
					n++;
				}
				aufwand++;
			} while (n < maxRunden);
			sigma /= 2.0;
			n = 0;
			aufwand++;
			
			/** TODO HIER EXPEREMENTIEREN ***/
			/* Also hier soll verhindert werden, dass er zu frueh aufhoert. 
			 * wenn der beste fitness-Wert nicht gut genug ist wird sigma erhoeht
			 *  und dann bricht er "while (sigma > sigmaMin);" hier nicht ab
			*/
			if(sigma < sigmaMin && fitnessBest > mindestFitness)	{
				sigma *= 2;
			}
			
			/* TODO bei schlechten gewaehlten Parametern, dauert es zu lange und Ergebnis ist auch nicht toll */
			/* bei "mindestFitness = 0.20"  und grad=1 endet das Programm nicht; weil es keinen besseren Fitness-wert gibt */
			if(aufwand > 100000) {
				System.out.println("*** ABBRUCH - Aufwand ist zu hoch. \n\tBitte bessere Parameter waehlen !!!");
				break;
			}
		} while (sigma > sigmaMin);
		
	}

	
	
	public void mutation(double mutant[], double bestMutatant[], double sigma) {
		for (int i = 0; i < mutant.length; i++) {
			//TODO testen... beide sind ca. gleich gut? 
			//mutant[i] = ((r.nextGaussian() * sigma) + bestMutatant[i]); // Eugen 
			mutant[i] = bestMutatant[i] + sigma * (r.nextGaussian() - 0.5) ; // Heinrich , aus einem Buch
		}

	}
	

	public static void main(String[] args) {
		int grad = 2;
		for (int i = 0; i < 1; i++) {
			MS_HeikoGrams2 m = new MS_HeikoGrams2(grad, 30); //XXX wenig runden => TOP Ergebnis !!!!!! 
			m.optimieren();
			m.ergebnisAusgabe();
		}
		
	}
}
 